package brainbots;


/**Class for simulating world dynamics, synchronizing process to real time*/
public class SynchronousSimulator implements Runnable
{
    private long delay=100;//time delay between steps, ms
    private double timeScale=1.0;//time scale (dt ~= (delay*0.001)*timeScale)
    private long oldTime = 0;
    private double maxStep = 0.01; ///maximum time grain
    
    private World world=null;
    
    private double timeElapsed = 0.0;
    
    private boolean requestedStop = false;
    private Runnable onStep = null;
    
    public void setTimeGrain(double dt){
        this.maxStep = dt;
    }
    
    public void setDelay(long delayMs){
        delay = delayMs;
    }
    public void setTimeScale(double timeScale){
        this.timeScale = timeScale;
    }
    
    /**Set runnable, that would be called, whed step is performed. If null, nothrin is called*/
    public void setStepHandler(Runnable handler)
    {
        onStep = handler;
    }
    public SynchronousSimulator(World w)
    {
        world = w;
    }
    public void resetTimer()
    {
        timeElapsed = 0.0;
    }
    
    public void run()
    {
        oldTime = System.currentTimeMillis();
        
        while (! requestedStop){
            long time = System.currentTimeMillis();
            double dt = (time - oldTime)*0.001*timeScale;
            timeElapsed += dt;
            oldTime = time;
            while (dt > maxStep){
                world.simulate(maxStep);
                dt -= maxStep;
            }         
            if (dt>0){
                world.simulate(dt);
            }
            
            if (onStep != null)
                onStep.run();
                
            try{
                Thread.sleep(delay);
            }catch (InterruptedException e){
				e.printStackTrace();
                return;
			}
        }
        
    }
}